home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1998 August / PC Plus SuperCD 50a Issue 142 (CD142a) (August 1998).iso / trial / demon / TURNPIKE.1 / CLASSES.ZIP / sun / tools / ZIP / ZipFile.class (.txt) < prev    next >
Encoding:
Java Class File  |  1997-04-14  |  3.8 KB  |  238 lines

  1. package sun.tools.zip;
  2.  
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.RandomAccessFile;
  7. import java.util.Enumeration;
  8. import java.util.Hashtable;
  9.  
  10. public class ZipFile implements ZipConstants {
  11.    private RandomAccessFile file;
  12.    private String path;
  13.    private Hashtable table;
  14.    long cenpos;
  15.    private long endpos;
  16.    private long pos;
  17.    private static final int INBUFSIZ = 64;
  18.  
  19.    public ZipFile(String var1) throws ZipFormatException, IOException {
  20.       this.file = new RandomAccessFile(var1, "r");
  21.       this.path = var1;
  22.       this.init();
  23.    }
  24.  
  25.    public ZipFile(File var1) throws ZipFormatException, IOException {
  26.       this(var1.getPath());
  27.    }
  28.  
  29.    public ZipEntry getEntry(String var1) {
  30.       return (ZipEntry)this.table.get(var1);
  31.    }
  32.  
  33.    public InputStream getInputStream(ZipEntry var1) throws ZipFormatException, IOException {
  34.       return new ZipFileInputStream(this, var1);
  35.    }
  36.  
  37.    public String getPath() {
  38.       return this.path;
  39.    }
  40.  
  41.    public Enumeration entries() {
  42.       return this.table.elements();
  43.    }
  44.  
  45.    public void close() throws IOException {
  46.       if (this.file != null) {
  47.          this.file.close();
  48.          this.file = null;
  49.       }
  50.  
  51.    }
  52.  
  53.    synchronized int read(long var1, byte[] var3, int var4, int var5) throws IOException {
  54.       if (var1 != this.pos) {
  55.          this.file.seek(var1);
  56.       }
  57.  
  58.       int var6 = this.file.read(var3, var4, var5);
  59.       if (var6 > 0) {
  60.          this.pos = var1 + (long)var6;
  61.       }
  62.  
  63.       return var6;
  64.    }
  65.  
  66.    synchronized int read() throws IOException {
  67.       if (this.pos != this.pos) {
  68.          this.file.seek(this.pos);
  69.       }
  70.  
  71.       int var1 = this.file.read();
  72.       if (var1 > 0) {
  73.          ++this.pos;
  74.       }
  75.  
  76.       return var1;
  77.    }
  78.  
  79.    private void init() throws ZipFormatException, IOException {
  80.       if (!this.findEnd()) {
  81.          throw new ZipFormatException("Could not find END header");
  82.       } else {
  83.          byte[] var1 = new byte[22];
  84.          RandomAccessFile var2 = this.file;
  85.          var2.readFully(var1, 0, var1.length);
  86.          byte[] var11 = ZipConstants.ENDSIG;
  87.          if (!checkSig(var1, 0, var11)) {
  88.             throw new ZipFormatException("Invalid END header signature");
  89.          } else {
  90.             this.cenpos = (long)(var1[16] & 255 | (var1[17] & 255) << 8 | (var1[18] & 255 | (var1[19] & 255) << 8) << 16);
  91.             int var12 = (int)((long)(var1[12] & 255 | (var1[13] & 255) << 8 | (var1[14] & 255 | (var1[15] & 255) << 8) << 16));
  92.             if (this.cenpos + (long)var12 != this.endpos) {
  93.                throw new ZipFormatException("Invalid END header format");
  94.             } else {
  95.                int var3 = var1[10] & 255 | (var1[11] & 255) << 8;
  96.                if (var3 * 46 > var12) {
  97.                   throw new ZipFormatException("Invalid END header format");
  98.                } else if ((var1[8] & 255 | (var1[9] & 255) << 8) != var3) {
  99.                   throw new ZipFormatException("Contains more than one drive");
  100.                } else {
  101.                   this.file.seek(this.cenpos);
  102.                   byte[] var4 = new byte[var12];
  103.                   RandomAccessFile var5 = this.file;
  104.                   var5.readFully(var4, 0, var4.length);
  105.                   this.table = new Hashtable(var3);
  106.  
  107.                   int var19;
  108.                   int var27;
  109.                   for(int var13 = 0; var13 < var12; var13 += var27 + (var4[var19] & 255 | (var4[var19 + 1] & 255) << 8)) {
  110.                      if (!checkSig(var4, var13, ZipConstants.CENSIG)) {
  111.                         throw new ZipFormatException("Invalid CEN header signature");
  112.                      }
  113.  
  114.                      int var6 = var13 + 28;
  115.                      var6 = var4[var6] & 255 | (var4[var6 + 1] & 255) << 8;
  116.                      if (var6 == 0 || var13 + 46 + var6 > var12) {
  117.                         throw new ZipFormatException("Invalid CEN header format");
  118.                      }
  119.  
  120.                      String var7 = new String(var4, 0, var13 + 46, var6);
  121.                      ZipEntry var8 = new ZipEntry(var7);
  122.                      var19 = var13 + 42;
  123.                      var27 = var4[var19] & 255 | (var4[var19 + 1] & 255) << 8;
  124.                      int var10 = var19 + 2;
  125.                      var8.locpos = (long)(var27 | (var4[var10] & 255 | (var4[var10 + 1] & 255) << 8) << 16);
  126.                      var19 = var13 + 20;
  127.                      var27 = var4[var19] & 255 | (var4[var19 + 1] & 255) << 8;
  128.                      var10 = var19 + 2;
  129.                      if (var8.locpos + (long)(var27 | (var4[var10] & 255 | (var4[var10 + 1] & 255) << 8) << 16) > this.cenpos) {
  130.                         throw new ZipFormatException("Invalid CEN header format");
  131.                      }
  132.  
  133.                      var19 = var13 + 24;
  134.                      var27 = var4[var19] & 255 | (var4[var19 + 1] & 255) << 8;
  135.                      var10 = var19 + 2;
  136.                      var8.length = (long)(var27 | (var4[var10] & 255 | (var4[var10 + 1] & 255) << 8) << 16);
  137.                      var19 = var13 + 12;
  138.                      var27 = var4[var19] & 255 | (var4[var19 + 1] & 255) << 8;
  139.                      var10 = var19 + 2;
  140.                      var8.mtime = (long)(var27 | (var4[var10] & 255 | (var4[var10 + 1] & 255) << 8) << 16);
  141.                      if (this.table.put(var8.getPath(), var8) != null) {
  142.                         throw new ZipFormatException("Invalid CEN header format");
  143.                      }
  144.  
  145.                      var27 = 46 + var6;
  146.                      var19 = var13 + 30;
  147.                      var27 += var4[var19] & 255 | (var4[var19 + 1] & 255) << 8;
  148.                      var19 = var13 + 32;
  149.                   }
  150.  
  151.                   if (this.table.size() != var3) {
  152.                      throw new ZipFormatException("Invalid CEN header format");
  153.                   }
  154.                }
  155.             }
  156.          }
  157.       }
  158.    }
  159.  
  160.    private boolean findEnd() throws IOException {
  161.       long var1 = this.file.length();
  162.       this.file.seek(var1);
  163.       long var3 = var1 - 65535L;
  164.       var3 = var3 <= 0L ? 0L : var3;
  165.       byte[] var5 = new byte[68];
  166.       int var6 = 64;
  167.  
  168.       for(int var7 = 4; var7-- > 0; var5[var6++] = 0) {
  169.       }
  170.  
  171.       this.pos = var1;
  172.  
  173.       while(this.pos > var3) {
  174.          var6 = (int)(this.pos - var3);
  175.          var6 = var6 <= 64 ? var6 : 64;
  176.          this.pos -= (long)var6;
  177.          this.file.seek(this.pos);
  178.          this.file.readFully(var5, 0, var6);
  179.  
  180.          while(true) {
  181.             --var6;
  182.             if (var6 <= 0) {
  183.                break;
  184.             }
  185.  
  186.             if (checkSig(var5, var6, ZipConstants.ENDSIG)) {
  187.                this.endpos = this.pos + (long)var6;
  188.                if (var1 - this.endpos >= 22L) {
  189.                   this.file.seek(this.endpos);
  190.                   byte[] var12 = new byte[22];
  191.                   RandomAccessFile var8 = this.file;
  192.                   var8.readFully(var12, 0, var12.length);
  193.                   int var13 = var12[20] & 255 | (var12[21] & 255) << 8;
  194.                   if (this.endpos + 22L + (long)var13 == var1) {
  195.                      this.file.seek(this.endpos);
  196.                      this.pos = this.endpos;
  197.                      return true;
  198.                   }
  199.                }
  200.             }
  201.          }
  202.       }
  203.  
  204.       return false;
  205.    }
  206.  
  207.    static final boolean checkSig(byte[] var0, int var1, byte[] var2) {
  208.       for(int var3 = 0; var3 < 4; ++var3) {
  209.          if (var0[var1 + var3] != var2[var3]) {
  210.             return false;
  211.          }
  212.       }
  213.  
  214.       return true;
  215.    }
  216.  
  217.    static final boolean checkSig(byte[] var0, byte[] var1) {
  218.       return checkSig(var0, 0, var1);
  219.    }
  220.  
  221.    static final void setBytes(byte[] var0, int var1, int var2, int var3) {
  222.       while(var2-- > 0) {
  223.          var0[var1++] = (byte)var3;
  224.       }
  225.  
  226.    }
  227.  
  228.    static final int getWord(byte[] var0, int var1) {
  229.       return var0[var1] & 255 | (var0[var1 + 1] & 255) << 8;
  230.    }
  231.  
  232.    static final long getLong(byte[] var0, int var1) {
  233.       int var10000 = var0[var1] & 255 | (var0[var1 + 1] & 255) << 8;
  234.       int var2 = var1 + 2;
  235.       return (long)(var10000 | (var0[var2] & 255 | (var0[var2 + 1] & 255) << 8) << 16);
  236.    }
  237. }
  238.